﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using CommonTools;
using CommonTools.Controls;
using WeifenLuo.WinFormsUI.Docking;
using shop.Bll;
using shop.Model;
using shop.Properties;
using shop.Bll.BasicInfo;

namespace shop.Logi
{
    /// <summary> 退换货登记 </summary>
    public partial class RefundRegistForm : DockContent, IToolStripMergableForm, 
        IDocForm<shop.Model.RefundRegist>
    {
        #region 属性, 字段

        /// <summary>
        /// 单据bll, 直接修改父类的内容
        /// </summary>
        public RefundRegistBll DocBll { set; get; }

        /// <summary>
        /// 单据 直接修改父类的内容
        /// </summary>
        public RefundRegist Doc
        {
            set
            {
                this._document = value ?? new RefundRegist();
                this.LoadDoc();
            }
            get => this._document;
        }

        private RefundRegist _document;

        private bool _isEditing = false;

        JRefundReasonBll jrBll = new JRefundReasonBll();

        #endregion 属性, 字段

        #region 构造函数

        public RefundRegistForm()
        {
            InitializeComponent();


            //检查权限, 需要在Doc赋值前修改
            RightHelper.CheckRight(this);


            //更换用户事件,检查权限 
            UserBll.UserChanged += () => RightHelper.CheckRight(this);


            //单据的Model, bll, 注意要先赋值bll,再赋值Model
            this.DocBll = new RefundRegistBll();
            this.Doc = new RefundRegist() { OccurDate = DateTime.Today};

            //this.box_RefundFrom.LazyInitItemsAsync(
            //    () => new[] { "无", "小额打款", "支付转款", "后台退款" });


            this.box_RefundFrom.LazyInitItems(
                ()=> new JRefundFromBll().Query(null), nameof(JRefundFrom.Name),
                new[] {nameof(JRefundFrom.Name)}, null,true);


            //
            this.box_Reason.LazyInitItems<JRefundReason>(
                () => jrBll.Query1Level(), 
                nameof(JRefundReason.Name),
            //new[] { nameof(JRefundReason.Name), nameof(JRefundReason.Name2), nameof(JRefundReason.Name3) }, null, true);
            new[] { nameof(JRefundReason.Code), nameof(JRefundReason.Name) }, null, true);


            //
            this.sta_Err.Text = "";
            this.sta_checked.Text = "";
            this.sta_LastTime.Text = "";
            this.sta_SelectionSum.Text = "";
        }

        public RefundRegistForm(IDoc doc)
            : this()
        {
            this.Doc = doc as RefundRegist;
        }

        #endregion 构造函数


        #region 实现IDocForm的接口: 新增,保存,创建窗口,显示窗口,

        /// <summary>
        /// 重载的保存方法, 会在实际保存前, 检查单据内容
        /// </summary>
        public bool Save()
        {
            this.Validate();


            //不能绑定数据的,在这里赋值, combobox 控件绑定数据有问题, 只能手动赋值给单据Doc
            Doc.OccurDate = Doc.PreparedDate = box_OccurDate.Value;
            Doc.Reason2 = box_Reason2.Text;
            Doc.Reason3 = box_Reason3.Text;

            if (this.DocBll.Save(this.Doc, UserBll.CurrentUser, out var err) == false)
            {
                //保存失败
                MessageBox.Show(err, Properties.Resources.systemInformation, MessageBoxButtons.OK,
                    MessageBoxIcon.Information);

                this.sta_Err.SetMessage(err, true);
                return false;
            }
            else
            {
                this.sta_Err.SetMessage(shop.Model.CN.Msg_Save, true);

                //将按钮的状态改成只读
                DocFormHelper.SetSaveStatus(SaveStatus.ReadOnly, this, toolSave, this.toolModify, toolSaveModify);
                //this.Doc.Items = DocBll.GetItems(Doc);
                //grid.ResetBindings(false);
                this.Doc = DocBll.GetDocByNum(Doc.Number);

                MessageTip.ShowOk(shop.Model.CN.Msg_Save);   // "保存成功!"


                //显示数据  这里都应该用绑定
                if (this.Doc.LastModifyTime != null)
                    this.sta_LastTime.Text = this.Doc.LastModifyTime.Value.ToString("yyyy-MM-dd HH:mm:ss");
                else
                    this.sta_LastTime.Text = "";

                return true;
            }
        }

        /// <summary> 删除 </summary>
        public void Delete()
        {
            if (MessageBox.Show(shop.Model.CN.Msg_wantToDeleteDoc,   //"确认要删除此单据吗?" 
                    Properties.Resources.systemInformation, MessageBoxButtons.YesNo, MessageBoxIcon.Question)
                != DialogResult.Yes)
            {
                return;
            }

            if (this.DocBll.Delete(this.Doc, UserBll.CurrentUser, out var err))
            {
                MessageTip.ShowOk(shop.Model.CN.Msg_DocIsDeleted);   // "单据已删除!"
                this.Close();  //直接关闭窗体

            }
            else
            {

                //删除失败
                MessageBox.Show(err, Properties.Resources.systemInformation, MessageBoxButtons.OK,
                    MessageBoxIcon.Warning);

                this.sta_Err.SetMessage(err, true);
            }
        }

        private async void LoadDoc()
        {
            //通过绑定数据的方式 加载单据内容
            this.docBindingSource.DataSource = new List<RefundRegist>() { this.Doc };

            if (this.Doc != null && this.Doc.DocId > 0)
            {
                //图片
                this.refundImgPanel1.DocId = this.Doc.DocId;
                await this.refundImgPanel1.GetImages();

                if (this.Doc.LastModifyTime != null)
                    this.sta_LastTime.Text = this.Doc.LastModifyTime.Value.ToString("yyyy-MM-dd HH:mm:ss");
                else
                    this.sta_LastTime.Text = "";

                //保存状态, 这里会影响保存按钮的显示
                DocFormHelper.SetSaveStatus((this.Doc.DocId > 0 ? SaveStatus.ReadOnly : SaveStatus.CanSave),
                    this, this.toolSave, this.toolModify, this.toolSaveModify);
            }
            else
            {
                //控件赋值, 清空
                this.box_OccurDate.Value = DateTime.Today;
                this.sta_LastTime.Text = "";
                //保存状态, 这里会影响保存按钮的显示
                DocFormHelper.SetSaveStatus(SaveStatus.CanSave, this, this.toolSave, this.toolModify, this.toolSaveModify);
            }


            if(box_OccurDate.Value== null)
            {
                this.box_OccurDate.Value= this.Doc.OccurDate= DateTime.Today;
            }

            this.sta_Err.SetMessage(); //清空提示
        }


        /// <summary> 创建新窗体, 但是不显示出来 </summary>
        public IDocForm<RefundRegist> CreateForm(IDoc doc)
        {
            return new RefundRegistForm(doc);
        }

        #endregion 实现IDocForm的接口: 新增,保存,创建窗口,显示窗口,

        #region 上方菜单按钮

        /// <summary> 保存按钮, 实现三个状态切换: 保存,修改,保存修改 </summary>
        private void toolSave_Click(object sender, EventArgs e)
        {
            //直接保存
            this.Save();
        }

        /// <summary> 修改 </summary>
        private void toolModify_Click(object sender, EventArgs e)
        {
            if (toolSaveModify.Enabled)
            {
                //撤销
                //当前可以保存修改， 那么再点这个按钮就是撤销
                DocFormHelper.SetSaveStatus(SaveStatus.ReadOnly, this, this.toolSave, this.toolModify, this.toolSaveModify);

                //删除正在编辑记录
                EditingBll.Clear(this.Doc);

            }
            else
            {
                // 这时, 这个按钮是显示的文字是"修改", 
                //检查权限 不是自己的单据需要额外的权限
                if (this.Doc.PreparedBy != UserBll.CurrentUser.Name
                    && UserBll.CheckRight(this.DocBll.ModifyPermission) == false)
                {
                    MessageBox.Show(shop.Model.CN.Msg_NoRightToModifyOther, Properties.Resources.systemInformation, MessageBoxButtons.OK,
                        MessageBoxIcon.Warning);
                    this.sta_Err.SetMessage(shop.Model.CN.Msg_NoRightToModifyOther, true);
                }
                else
                {
                    //检查是否可以修改 
                    var status = this.DocBll.GetStatus(this.Doc);
                    if (status.EnableModify == false)
                    {
                        MessageBox.Show(status.Reason, Resources.systemInformation, MessageBoxButtons.OK, MessageBoxIcon.Warning);
                        this.sta_Err.SetMessage(status.Reason, true);
                        return;
                    }

                    //添加正在编辑记录
                    if (EditingBll.TryAdd(this.Doc, UserBll.CurrentUser, out var editing) == false)
                    {
                        string err = string.Format(shop.Model.CN.Msg_DocIsEditingByOther, editing.UserName, editing.EditTime);
                        MessageBox.Show(err, Resources.systemInformation, MessageBoxButtons.OK, MessageBoxIcon.Warning);
                        this.sta_Err.SetMessage(err, true);
                    }
                    else
                    {
                        //改变单据编辑状态
                        DocFormHelper.SetSaveStatus(SaveStatus.CanModify, this, this.toolSave, this.toolModify, this.toolSaveModify);
                        MessageTip.ShowOk(this, shop.Model.CN.Msg_docCanEdit);   // "可以编辑了!"
                    }

                }

            }
        }

        /// <summary> 保存修改 </summary>
        private void toolSaveModify_Click(object sender, EventArgs e)
        {
            //直接保存修改
            this.Save();
        }



        private void toolRefresh_Click(object sender, EventArgs e)
        {
            if (this.Doc != null)
            {
                this.Doc = this.DocBll.GetDoc(this.Doc.DocId);
            }
        }



        #region 打印

        /// <summary> 打印预览 </summary>
        private void toolPrintPreView_Click(object sender, EventArgs e)
        {
            if (this.Doc != null && this.Doc.DocId == 0)
            {
                MessageBox.Show(shop.Model.CN.Msg_SaveBeforePrint, Resources.systemInformation, MessageBoxButtons.OK,
                    MessageBoxIcon.Information);
                return;
            }

            this.PrintDoc(true);
        }

        /// <summary> 打印 </summary>
        private void toolPrint_Click(object sender, EventArgs e)
        {
            if (this.Doc != null && this.Doc.DocId == 0)
            {
                MessageBox.Show(shop.Model.CN.Msg_SaveBeforePrint, Resources.systemInformation, MessageBoxButtons.OK,
                    MessageBoxIcon.Information);
                return;
            }

            this.PrintDoc(false);
        }

        /// <summary> 打印 </summary>
        /// <param name="isPreview">是否预览</param>
        private void PrintDoc(bool isPreview)
        {
            //GtPrintEditor.GtPrintDocument printFile = GtPrintDocument.FromFile("合同结算模板");
            //if (printFile == null)
            //{
            //    MessageBox.Show(shop.Model.CN.Msg_CannotFindPrintTemplate, Resources.systemInformation, MessageBoxButtons.OK,
            //    MessageBoxIcon.Information);
            //    return;
            //}

            //// todo 参数按照模板进行调整 参数 
            //PrintParameter[] prs = new PrintParameter[]
            //{
            //    new PrintParameter("time"){ Value = DateTime.Now},
            //    new PrintParameter("打印次数"){ Value = this.Doc.PrintCount +1}, 
            //    new PrintParameter("doc"){ Value = this.Doc},
            //};

            //// todo 模板未实现这个代码 修改打印次数
            //// printFile.PrintSuccess += d =>  this.DocBll.AddPrintCount(this.Doc);      //PrintSuccess是打印成功事件

            //if (isPreview)
            //    printFile.PrintPreView(prs); //预览
            //else
            //    printFile.PrintChoosePrinter(prs);        //打印, 会提示先择打印机
        }

        #endregion


        /// <summary> 审核 </summary>
        private void toolCheck_Click(object sender, EventArgs e)
        {
            if (this.DocBll.CheckDocument(this.Doc, UserBll.CurrentUser, out var err) == true)
            {
                this.sta_Err.SetMessage();
                MessageTip.ShowOk(this, shop.Model.CN.Msg_ISchecked);    // "单据已审核！"
            }
            else
            {
                MessageBox.Show(err, Properties.Resources.systemInformation, MessageBoxButtons.OK,
                    MessageBoxIcon.Information);
                this.sta_Err.SetMessage(err, true);
            }
        }

        /// <summary> 反审核 </summary>
        private void toolUnCheck_Click(object sender, EventArgs e)
        {
            if (this.DocBll.UnCheckDocument(this.Doc, UserBll.CurrentUser, out var err) == true)
            {
                this.sta_Err.SetMessage();
                MessageTip.ShowOk(this, shop.Model.CN.Msg_DocIsUnCheck); // "单据已反审核！"
            }
            else
            {
                MessageBox.Show(err, Properties.Resources.systemInformation, MessageBoxButtons.OK,
                    MessageBoxIcon.Information);
                this.sta_Err.SetMessage(err, true);
            }
        }

        private void toolDelete_Click(object sender, EventArgs e)
        {
            this.Delete();
        }

        #endregion 上方菜单按钮

        #region 其他按钮



        private void btn_showQueryBox_Click(object sender, EventArgs e)
        {
            if (this.ParentForm is DocDockxx dd)
            {
                dd.toolQuery.PerformClick();  //点击查询按钮
            }
        }

        #endregion 其他按钮

        #region 实现合并工具栏的接口

        /// <summary> 实现合并工具栏的接口 </summary>
        public ToolStrip MergedToolStrip => this.toolStrip1;

        #endregion 实现合并工具栏的接口

        #region 窗体事件

        /// <summary> 窗体关闭事件 </summary>
        private void Form_FormClosing(object sender, FormClosingEventArgs e)
        {
            //this.grid.SaveWidthIni(this.GetType().Name);

            //如果当前正在编辑状态， 需要删除正在编辑记录
            if (this.toolSaveModify.Enabled)
                EditingBll.Clear(this.Doc);
        }

        private void Form_Load(object sender, EventArgs e)
        {
            //this.grid.ReLoadWidthIni(this.GetType().Name);

            this.refundImgPanel1.BeforeUpload = () =>
            {
                if (this.Doc?.DocId > 0)
                {
                    refundImgPanel1.DocId = this.Doc.DocId;

                    return new Result(true);
                }
                else
                {
                    return new Result(false, "请先保存再上传图片");
                }
            };
        }


        #endregion 窗体事件



        private void grid_CellEndEdit(object sender, unvell.ReoGrid.CellEndEditEventArgs e)
        {
            try
            {
                //if (e.Cell.Column == cl_LogiAccount.Index)
                //{
                //    GetLogi(e.Cell.Row, grid[e.Cell].IsNull(), false);
                //}
            }
            catch (Exception)
            {

                throw;
            }
        
        }




        private void grid_CellKeyUp(object sender, unvell.ReoGrid.Events.CellKeyDownEventArgs e)
        {
            if (e.Cell.Row<1)
            {
                return;
            }

            //if (e.Cell.Column == cl_LogiAccount.Index)
            //{
            //    GetLogi(e.Cell.Row, null, true);
            //}
        }





        private async void RefundRegistForm_KeyDown(object sender, KeyEventArgs e)
        {
            if ((Control.ModifierKeys & Keys.Control) == Keys.Control && e.KeyCode == Keys.V)//判断Ctrl+V键
            {
                await WaitUI.RunAsync(async () =>
                {
                    await this.refundImgPanel1.UploadFromClipboard(true);
                });
            }
        }

        private async void box_LogiNo_RequestValidate(FastTextBox arg1, FastValueArgs arg2)
        {
            if (arg2.ChangeMode == ChangeModeEnum.Clear)
            {
                return;
            }

            var list = await DocBll.Pickup(arg1.Text);

            if (list?.Any() == true)
            {
                var item = list?.FirstOrDefault();

                if (list.Count() > 1)
                {
                    var map = new Dictionary<string, string>()
                    {
                        {nameof(tradeItem.trade_no),"单号" },
                        {nameof(tradeItem.logistics_no),"快递单号" },
                        {nameof(tradeItem.warehouse),"仓库" },
                        {nameof(tradeItem.spec_no),"商家编码" },
                        {nameof(tradeItem.platform_goods_id),"产品ID" },
                    };
                    var bl = new Selector<tradeItem>()
                        .UseData(list)
                        .UseColumns(map)
                        .GetValue(out var res);

                    if (bl)
                    {
                        item = res;
                    }
                    else
                    {
                        return;
                    }
                }


                //需要合并 快递单号, 商品信息
                //var logiNo = list.AggregateStr(a => a.logistics_no);
                //var spec_no = list.AggregateStr(a => a.spec_no);
                //var platform_goods_id = list.AggregateStr(a => a.platform_goods_id);
                //var Stock = list.AggregateMergeStr(a => a.warehouse);
                //var shop = list.AggregateMergeStr(a => a.shop_name);

                this.Doc.LogiNo = box_LogiNo.Text = item.logistics_no;
                this.Doc.RefundQty = box_RefundQty.Value = item.num;
                this.Doc.platform_goods_id = box_platform_goods_id.Text = item.platform_goods_id;
                this.Doc.Stock = box_Stock.Text = item.warehouse;
                //this.Doc.Shop = box_Shop.Text = item.shop_name;
                this.Doc.trade_no = box_tradeNo.Text = item.trade_no ;
                this.Doc.RefundReason = box_RefundReason.Text = item.refund_status;
                //this.Doc.Wangwang = box_Wangwang.Text = item.buyer_nick;
            }

        }



        private async void Box_tradeNo_RequestValidate(FastTextBox arg1, FastValueArgs arg2)
        {
            if (arg2.ChangeMode == ChangeModeEnum.Clear)
            {
                return;
            }

            var list = await DocBll.Pickup(null, arg1.Text);

            if (list?.Any() == true)
            {
                var item = list?.FirstOrDefault();

                if (list.Count() > 1)
                {
                    var map = new Dictionary<string, string>()
                    {
                        {nameof(tradeItem.trade_no),"单号" },
                        {nameof(tradeItem.logistics_no),"快递单号" },
                        {nameof(tradeItem.warehouse),"仓库" },
                        //{nameof(tradeItem.spec_no),"商家编码" },
                        {nameof(tradeItem.platform_goods_id),"产品" },
                    };
                    var bl = new Selector<tradeItem>()
                        .UseData(list)
                        .UseColumns(map)
                        .GetValue(out var res);

                    if (bl)
                    {
                        item = res;
                    }
                    else
                    {
                        return;
                    }
                }


                this.Doc.LogiNo = box_LogiNo.Text = item.logistics_no;
                //this.Doc.spec_no = box_spec_no.Text = item.spec_no;
                this.Doc.RefundQty = box_RefundQty.Value = item.num;
                this.Doc.platform_goods_id = box_platform_goods_id.Text = item.platform_goods_id;
                this.Doc.Stock = box_Stock.Text = item.warehouse;
                this.Doc.RefundReason = box_RefundReason.Text = item.refund_status;
                //this.Doc.Shop = box_Shop.Text = item.shop_name;
                this.Doc.trade_no = box_tradeNo.Text = item.trade_no;
            }
        }

        private void box_Reason_SelectedIndexChanged(object sender, EventArgs e)
        {
            if(this.box_Reason.Text == string.Empty)
            {
                this.box_Reason2.Text = Doc.Reason2 = string.Empty;
                this.box_Reason3.Text = Doc.Reason3 = string.Empty;
                this.box_Reason.Text = Doc.Reason = string.Empty;

                this.box_Reason2.Items.Clear();
                this.box_Reason3.Items.Clear();

                return;
            }

            var item = this.box_Reason.SelectedItem as JRefundReason;
            if (item != null)
            {
                //this.box_Reason2.Text = Doc.Reason2 = item.Name2;
                //this.box_Reason3.Text = Doc.Reason3 = item.Name3;
                this.box_Reason.Text = Doc.Reason = item.Name;

                this.box_Reason2.Items.Clear();
                //this.box_Reason2.Items.AddRange(jrBll.Query2Level(item.Code).ToArray());

                this.box_Reason2.LazyInitItems<JRefundReason>(
                        () => jrBll.Query2Level(item.Code),
                        nameof(JRefundReason.Name),
                    new[] { nameof(JRefundReason.Code), nameof(JRefundReason.Name) }, null, true);

                //this.box_Reason2.DisplayMember = "Name";

                //this.box_Reason3.Items.Clear();
                //this.box_Reason3.DisplayMember = "Name";
            }
            else
            {
                //this.box_Reason2.Text = Doc.Reason2 = string.Empty;
                //this.box_Reason3.Text = Doc.Reason3 = string.Empty;
                this.box_Reason.Text = Doc.Reason = string.Empty;
                this.box_Reason3.Items.Clear();
                this.box_Reason3.Items.Clear();
            }
        }

        private void box_Reason2_SelectedIndexChanged(object sender, EventArgs e)
        {
            this.box_Reason3.Items.Clear();
            if(this.box_Reason2.SelectedItem == null)
            {

            }
            else
            {
                //this.box_Reason3.Items.AddRange(jrBll.Query3Level((this.box_Reason2.SelectedItem as JRefundReason).Code ).ToArray());
                var item = this.box_Reason2.SelectedItem as JRefundReason;

                this.box_Reason3.LazyInitItems<JRefundReason>(
                     () => jrBll.Query3Level(item.Code),
                     nameof(JRefundReason.Name),
                 new[] { nameof(JRefundReason.Code), nameof(JRefundReason.Name) }, null, true);

            }
        }

        private void btnChooseReason_Click(object sender, EventArgs e)
        {
            var model = FastBox.GetValue<JRefundReason, JRefundReasonBll>(null,true);

            if (model != null)
            {
                var res = jrBll.Get3Names(model);

                if (res != null)
                {
                    this.Doc.Reason = this.box_Reason.Text = res.Name;
                    this.Doc.Reason2 = this.box_Reason2.Text = res.Name2;
                    this.Doc.Reason3 = this.box_Reason3.Text = res.Name3;
                }
            }
        }
    }






}


 
